import { _decorator, Component, Node, v3, tween, Vec3, v2 } from 'cc';
import { GlobalTmpData } from '../../../Init/Config/GlobalTmpData';
import EventManager from '../../../Init/Managers/EventManager';
import { EventTypes } from '../../../Init/Managers/EventTypes';
import { StorageSystem } from '../../../Init/SystemStorage/StorageSystem';
import { LevelDataTmp, StorageTemp } from '../../../Init/SystemStorage/StorageTemp';
import { UIEnum } from '../../../Init/SystemUI/UIEnum';
import { UISystem } from '../../../Init/SystemUI/UISystem';
import { ModelsLayer } from '../Custom/ModelsLayer';
import { BulletLayer } from '../Custom/BulletLayer';
import { EffectLayer } from '../Custom/EffectLayer';
import { EnemyLayer } from '../Custom/EnemyLayer';
import { ZombieLayer } from '../Custom/ZombieLayer';
import { BasicLayer } from './Basic/BasicLayer';
import { BasicMountLayer } from './Basic/BasicMountLayer';
import { GameTmpData } from './GameTmpData';
import { GlobalConfig } from '../../../Init/Config/GlobalConfig';
import { LevelConfig } from '../../../Init/Config/LevelConfig';
const { ccclass, property } = _decorator;

@ccclass('LevelManager')
export class LevelManager extends Component {
    @property(Node)
    private layerNodeArr: Node[] = []; //需要继承 BasicMountLayer

    @property(Node)
    private perfabsLayer: Node = null; //用于存放游戏当前关卡场景中所有的物体


    private _isPause = false;
    private _isOver = false;
    //记录关卡数据
    private _lvData: LevelDataTmp = null;
    //记录是否运行游戏
    private _isRun = false;

    // #region -------------------生命周期---------------
    protected onLoad() {
        this.onEvents();
        this.initLayers();
        this.initCustomLayers();

    }

    protected onEvents() {
        EventManager.on(EventTypes.GameEvents.GamePause, this.onGamePause, this);
        EventManager.on(EventTypes.GameEvents.GameResume, this.onGameResume, this);
        EventManager.on(EventTypes.GameEvents.GameRun, this.onGameRun, this);
        EventManager.on(EventTypes.GameEvents.GameOver, this.onGameOver, this);
        EventManager.on(EventTypes.GameEvents.SetGameTimeScale, this.onSetGameTimeScale, this);
        EventManager.on(EventTypes.GameEvents.GameLoadFinish, this.onGameLoadFinish, this);
        //
        EventManager.on(EventTypes.TouchEvents.TouchStart, this.onTouchStart, this);
    }

    protected onEnable() {
        this.reset();
        this.startRecord();
        this.setData();
    }

    protected start() {

    }

    protected onDisable() {
        this.resetLayers();
        this.resetCustomLayers();
    }

    /**重置状态 */
    protected reset() {
        this._isPause = false;
        this._isOver = false;
        this._isRun = false;
        GlobalTmpData.timeScale = 1.0;
        GlobalTmpData.reset();
        GameTmpData.reset();

        this.resetLayers();
    }

    protected setData() {
        this._lvData = this.getcurLvData();
        this.setLayersData(this._lvData);
        this.setCustomLayersData(this._lvData);
    }

    protected update(dt) {
        this.updateRunRecord(dt);
        if (this._isPause || this._isOver) return;
        this.updateGameRecord(dt);
        let ft = dt * GlobalTmpData.timeScale;
        this.updateLayers(ft);
        this.updateCustomLayers(ft)
    }
    protected lateUpdate(dt) {
        if (this._isPause || this._isOver) return;
        let ft = dt * GlobalTmpData.timeScale;
        this.lateUpdateLayers(ft);
        this.lateUpdateCustomLayers(ft);
    }
    // #endregion

    // #region -------------------数据统计-----------
    /**数据统计开始 */
    private startRecord() {
        GlobalTmpData.Game.startTime = Date.now();
        GlobalTmpData.Game.totalTime = 0;
        GlobalTmpData.Game.endTime = 0;
    }
    //记录游戏运行时长(包括暂停)
    private updateRunRecord(dt) {
        GlobalTmpData.Game.totalTime += dt;
    }
    //记录游戏时长(不包括暂停)
    private updateGameRecord(dt) {
        if (this._isOver) return;
        GlobalTmpData.Game.gameTime += dt;
    }
    private stopRecord() {
        GlobalTmpData.Game.endTime = Date.now();
    }

    // #endregion

    // #region -------------------挂载层级管理--------------
    //挂载的层级组件
    private mountLayers: BasicMountLayer[] = [];

    /**初始化层级数据 */
    protected initLayers() {
        for (let i = 0; i < this.layerNodeArr.length; i++) {
            const e = this.layerNodeArr[i];
            const cmp = e.getComponent(BasicMountLayer);
            this.mountLayers.push(cmp);
            cmp.initLayer();
        }
    }
    /**重置层级数据 */
    protected resetLayers() {
        this.mountLayers.forEach(layer => {
            layer.reset();
        });
    }
    /**设定层级数据 */
    protected setLayersData(d) {
        this.mountLayers.forEach(layer => {
            layer.setData(d);
        });

    }
    /**更新层级数据 */
    protected updateLayers(dt) {
        this.mountLayers.forEach(layer => {
            layer.customUpdate(dt);
        });
    }
    /**更新层级数据 */
    protected lateUpdateLayers(dt) {
        this.mountLayers.forEach(layer => {
            layer.customLateUpdate(dt);
        });
    }

    // #endregion

    // #region -------------------自定义层级管理--------------
    //自定义的层级组件
    private customLayers: BasicLayer[] = [];
    protected initCustomLayers() {
        this.customLayers.push(new ModelsLayer(this.perfabsLayer));
        this.customLayers.push(new ZombieLayer(this.perfabsLayer));
        this.customLayers.push(new EnemyLayer(this.perfabsLayer));
        this.customLayers.push(new BulletLayer(this.perfabsLayer));
        this.customLayers.push(new EffectLayer(this.perfabsLayer));
        this.customLayers.forEach(e => { e.initLayer() });
    }
    protected resetCustomLayers() {
        this.customLayers.forEach(e => { e.reset() });
    }
    protected setCustomLayersData(d?) {
        this.customLayers.forEach(e => { e.setData(d) });
    }
    protected updateCustomLayers(dt) {
        this.customLayers.forEach(e => { e.customUpdate(dt) });
    }
    protected lateUpdateCustomLayers(dt) {
        this.customLayers.forEach(e => { e.customLateUpdate(dt) });
    }
    // #endregion

    // #region -------------------私有方法------
    private _endArr = [22222];
    private _randArr = [10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009, 10010, 10011, 10012, 10017];
    //获取关卡配置数据+路段数据组合
    protected getcurLvData(): LevelDataTmp {
        let levelAssets = StorageSystem.getData().levelAssets;
        let lv = levelAssets.curLv;

        GlobalTmpData.Game.isGuideLv = lv == 1;

        let idArr = LevelConfig[lv];
        if (!LevelConfig[lv]) {
            if (levelAssets.randLvArr && levelAssets.randLvArr.length <= 0) {
                idArr = [10001];
                //----随机关卡
                //10-15关：中间拼接5个场景；
                //16-20关；中间拼接6个场景；
                //20关以后统一随机7个场景进行拼凑；
                let randArr = [];
                this._randArr.forEach(e => { randArr.push(e) });

                let pathLen = 0;
                if (lv <= 15) {
                    pathLen = 5;
                } else if (lv < 20) {
                    pathLen = 6;
                } else {
                    pathLen = 7;
                }

                //随机路段            
                for (let i = 0; i < pathLen; i++) {
                    let _index = Math.floor(Math.random() * randArr.length);
                    idArr.push(randArr[_index]);
                    randArr.splice(_index, 1);
                }
                // 随机终点
                idArr.push(this._endArr[Math.floor(Math.random() * this._endArr.length)]);

                //存储
                levelAssets.randLvArr = [];
                idArr.forEach(e => { levelAssets.randLvArr.push(e) });
                StorageSystem.saveData();

            } else {
                idArr = [];
                levelAssets.randLvArr.forEach(e => { idArr.push(e) });
            }
        }

        console.log('关卡 ' + lv + ': ' + idArr);

        let data = new LevelDataTmp();
        data.lv = lv;
        let offsetY = 0;
        let offsetZ = 0;

        let preCy = 0;
        let curY = 0;

        //0-起点 
        for (let i = 0; i < idArr.length; i++) {
            const id = idArr[i];
            const rec = StorageSystem.getLvData(id);

            const wallRec = rec.colliders['wall'][0];

            let cy = wallRec.s.y * 0.5;

            if (i == 0) {
                //起点                
                offsetY = 0;
                curY = wallRec.p.y;
            } else {
                // offsetY =计算后的Y - initY
                curY += preCy + cy;
                offsetY = curY - wallRec.p.y;
            }
            offsetZ = - offsetY * GlobalConfig.Scale2DTo3D; //3d
            preCy = cy;

            if (i == idArr.length - 2) { //默认设置倒数第二个路段为终点线
                //终点
                data.endArea.p.set(rec.endArea.p.x, rec.endArea.p.y + offsetY, rec.endArea.p.z);
                data.endArea.s.set(rec.endArea.s);
            }
            // console.log(offsetY);

            //障碍物
            for (const key in rec.colliders) {
                if (!data.colliders[key]) {
                    data.colliders[key] = []
                };
                rec.colliders[key].forEach(e => {
                    data.colliders[key].push({
                        p: v3(e.p.x, e.p.y + offsetY, e.p.z), s: v2(e.s), r: v3(e.r)
                    });
                })
            }
            //敌人2d
            for (const key in rec.enemys) {
                if (!data.enemys[key]) {
                    data.enemys[key] = []
                };
                rec.enemys[key].forEach(e => {
                    data.enemys[key].push({
                        p: v3(e.p.x, e.p.y + offsetY, e.p.z), s: v2(e.s), r: v3(e.r),
                        isBoss: e.isBoss, hp: e.hp, isStatic: e.isStatic
                    });
                })
            }
            //道具2d
            for (const key in rec.props) {
                if (!data.props[key]) {
                    data.props[key] = []
                };
                rec.props[key].forEach(e => {
                    data.props[key].push({
                        p: v3(e.p.x, e.p.y + offsetY, e.p.z), s: v2(e.s), r: v3(e.r)
                    });
                })
            }
            //模型 3d
            for (const key in rec.models) {
                if (!data.models[key]) {
                    data.models[key] = []
                };
                rec.models[key].forEach(e => {
                    data.models[key].push({
                        p: v3(e.p.x, e.p.y, e.p.z + offsetZ), s: v3(e.s), r: v3(e.r)
                    });
                })
            }
            //宝箱位置
            for (const key in rec.boxMarks) {
                const e = rec.boxMarks[key];
                data.boxMarks.push(v3(e.x, e.y + offsetY, 0));
            }

            //钥匙位置
            for (const key in rec.keyMarks) {
                const e = rec.keyMarks[key];
                data.keyMarks.push(v3(e.x, e.y + offsetY, 0));
            }
        }

        return data;
    }

    private initPos = GlobalConfig.Camera.initPos;
    private initRot = GlobalConfig.Camera.initRot;
    private lvCamraPos = GlobalConfig.Camera.lvCamraPos;
    private lvCamraRot = GlobalConfig.Camera.lvCamraRot;
    /**镜头引导 */
    private showCameraGuide() {
        //镜头动画
        let pos = v3(this.initPos);
        let rot = v3(this.initRot);
        let t = 2;
        tween(pos).to(t, { y: this.lvCamraPos.y, z: this.lvCamraPos.z }, {
            easing: 'sineInOut', onUpdate: () => {
                EventManager.emit(EventTypes.CameraEvents.SetCameraSelfPos, pos);
            }
        }).start();
        tween(rot).to(t, { x: this.lvCamraRot.x, y: this.lvCamraRot.y, z: this.lvCamraRot.z }, {
            easing: 'sineInOut', onUpdate: () => {
                EventManager.emit(EventTypes.CameraEvents.SetCameraSelfRot, rot);
            }
        }).call(() => {
            EventManager.emit(EventTypes.GameEvents.GameRun);
            EventManager.emit(EventTypes.GuideEvents.ShowGuideAnim);
        }).start();
    }

    //引导关卡镜头
    private showGuideLvCamera() {
        let pos = v3(this.initPos);
        EventManager.emit(EventTypes.CameraEvents.SetCameraSelfPos, pos);

        tween(pos).delay(4).to(3, { y: this.lvCamraPos.y, z: this.lvCamraPos.z }, {
            easing: "sineInOut", onUpdate: () => {
                EventManager.emit(EventTypes.CameraEvents.SetCameraSelfPos, pos);
            }
        }).start();

        let rot = v3(this.initRot);
        EventManager.emit(EventTypes.CameraEvents.SetCameraSelfRot, rot);
        tween(rot).delay(4).to(3, { x: this.lvCamraRot.x, y: this.lvCamraRot.y, z: this.lvCamraRot.z }, {
            easing: 'sineInOut', onUpdate: () => {
                EventManager.emit(EventTypes.CameraEvents.SetCameraSelfRot, rot);
            }
        }).start();
    }

    // #endregion

    // #region -------------------事件------------
    protected onGameLoadFinish() {
        UISystem.showUI(UIEnum.Collision2DUI, this._lvData);

        let lv = StorageSystem.getData().levelAssets.curLv;
        if (lv == 1) {
            //---引导关卡自动进入
            //设置角度
            EventManager.emit(EventTypes.CameraEvents.SetCameraSelfPos, this.lvCamraPos);
            EventManager.emit(EventTypes.CameraEvents.SetCameraSelfRot, this.lvCamraRot);
            this._isRun = true;
            this.showGuideLvCamera();
            setTimeout(() => {
                EventManager.emit(EventTypes.GameEvents.GameRun);
            }, 500);
        } else {
            //---正常关卡
            //设置相机初始角度+位置
            EventManager.emit(EventTypes.CameraEvents.SetCameraSelfPos, this.initPos);
            EventManager.emit(EventTypes.CameraEvents.SetCameraSelfRot, this.initRot);

        }
    }

    protected onTouchStart() {
        if (this._isRun) return;
        this._isRun = true;
        UISystem.hideUI(UIEnum.HomeUI);
        this.showCameraGuide();
        UISystem.hideUI(UIEnum.MapUI);
    }

    /**暂停 */
    protected onGamePause() {
        this._isPause = true;
        GlobalTmpData.Game.isGamePause = true;
    }
    /**继续 */
    protected onGameResume() {
        this._isPause = false;
        GlobalTmpData.Game.isGamePause = false;
    }
    protected onSetGameTimeScale(n) {
        if (undefined !== n) {
            GlobalTmpData.timeScale = n;
        }
    }

    /**结束 */
    protected onGameOver(isWin?: boolean) {
        if (this._isOver) return;
        GlobalTmpData.Game.isGameOver = true;
        this._isOver = true;
        UISystem.hideUI(UIEnum.Collision2DUI);
        UISystem.hideUI(UIEnum.FakeLevelUI);
        this.stopRecord();

        // 关卡结束事件埋点
        // let stageId: number = 10000 + GlobalTmpData.Game.gameLevel;
        // let stageName: string = "第" + GlobalTmpData.Game.gameLevel + "关";
        // if (isWin) uniSdk.Global.reportAldStageEnd(stageId, stageName);
        // else uniSdk.Global.reportAldStageFail(stageId, stageName);

        //移除关卡随机路段
        StorageSystem.setData((d) => {
            d.levelAssets.randLvArr = [];
        }, true)
    }

    protected onGameRun() {
        GlobalTmpData.Game.isGameRun = true;
        GlobalTmpData.Game.gameLevel = StorageSystem.getData().levelAssets.curLv;
        //
        UISystem.showUI(UIEnum.FakeLevelUI);
        // 关卡开始事件埋点
        // let stageId: number = 10000 + GlobalTmpData.Game.gameLevel;
        // let stageName: string = "第" + GlobalTmpData.Game.gameLevel + "关";
        // uniSdk.Global.reportAldStageStart(stageId, stageName);
    }
    // #endregion
}

